﻿namespace HelperLibrary;

/// <summary>
/// Http辅助类
/// </summary>
public class HTTPHelper
{
    /// <summary>
    /// 默认超时
    /// </summary>
    const int defaultTimeout = 30 * 1000;

    private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
    {
        return true;
    }
    /// <summary>
    /// GET
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="url"></param>
    /// <param name="token"></param>
    /// <param name="timeout"></param>
    /// <returns></returns>
    public static async Task<T?> Get<T>(string url, string? token = null, int timeout = defaultTimeout)
    {
        try
        {
            string res = await HttpGet(url, token, timeout);
            return JsonConvert.DeserializeObject<T>(res);
        }
        catch (Exception)
        {
            throw;
        }
    }

    /// <summary>
    /// GET
    /// </summary>
    /// <param name="url"></param>
    /// <param name="token"></param>
    /// <param name="timeout"></param>
    /// <returns></returns>
    public static async Task<string> HttpGet(string url, string? token = null, int timeout = defaultTimeout)
    {
        try
        {
            HttpClient client = new HttpClient();
            if (url.StartsWith("https", System.StringComparison.OrdinalIgnoreCase))
            {
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 |
                                                       SecurityProtocolType
                                                           .Tls12; //必须加上这一句，根据需要更改值
                var handler = new HttpClientHandler();
                handler.ServerCertificateCustomValidationCallback = CheckValidationResult;
                client = new HttpClient(handler);
                client.DefaultRequestVersion = HttpVersion.Version11;
            }
            client.Timeout = TimeSpan.FromMilliseconds(timeout);
            var msg = new HttpRequestMessage(HttpMethod.Get, url);
            if (!string.IsNullOrEmpty(token))
            {
                msg.Headers.Add("token", token);
            }
            HttpResponseMessage response = await client.SendAsync(msg);
            response.EnsureSuccessStatusCode();
            StreamReader myreader = new StreamReader(response.Content.ReadAsStream(), Encoding.UTF8);
            string responseText = myreader.ReadToEnd();
            myreader.Close();
            return responseText;
        }
        catch (Exception ex)
        {
            Log.WriteException(new Exception($"GET Error: {ex.Message}, {url}, {token}"));
            throw;
        }
    }

    /// <summary>
    /// Post
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="url"></param>
    /// <param name="param"></param>
    /// <param name="token"></param>
    /// <param name="timeout"></param>
    /// <returns></returns>
    public static async Task<T?> Post<T>(string url, dynamic param, string? token = null, int timeout = defaultTimeout)
    {
        try
        {
            string paramStr = JsonConvert.SerializeObject(param);
            string res = await HttpPost(url, paramStr, token, timeout);
            return JsonConvert.DeserializeObject<T>(res);
        }
        catch (Exception)
        {
            throw;
        }
    }

    /// <summary>
    /// Post
    /// </summary>
    /// <param name="url"></param>
    /// <param name="json"></param>
    /// <param name="token"></param>
    /// <param name="timeout"></param>
    /// <returns></returns>
    public static async Task<string> HttpPost(string url, string json, string? token = null, int timeout = defaultTimeout)
    {
        try
        {
            HttpClient client = new HttpClient();
            if (url.StartsWith("https", System.StringComparison.OrdinalIgnoreCase))
            {
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 |
                                                       SecurityProtocolType
                                                           .Tls12; //必须加上这一句，根据需要更改值
                var handler = new HttpClientHandler();
                handler.ServerCertificateCustomValidationCallback = CheckValidationResult;
                client = new HttpClient(handler);
                client.DefaultRequestVersion = HttpVersion.Version11;
            }

            client.Timeout = TimeSpan.FromMilliseconds(timeout);
            var msg = new HttpRequestMessage(HttpMethod.Post, url);
            if (!string.IsNullOrEmpty(token))
            {
                msg.Headers.Add("token", token);
            }
            msg.Content = new StringContent(json, Encoding.UTF8, "application/json");
            HttpResponseMessage response = await client.SendAsync(msg);
            //response.EnsureSuccessStatusCode();
            StreamReader myreader = new StreamReader(response.Content.ReadAsStream(), Encoding.UTF8);
            string responseText = myreader.ReadToEnd();
            myreader.Close();
            return responseText;
        }
        catch (Exception ex)
        {
            Log.WriteException(new Exception($"POST Error: {ex.Message}, {url}, {json}, {token}"));
            throw;
        }
    }

    /// <summary>
    /// Post
    /// </summary>
    /// <param name="url"></param>
    /// <param name="json"></param>
    /// <param name="token"></param>
    /// <param name="timeout"></param>
    /// <returns></returns>
    public static string AASHttpPost(string url, string json, string? token = null, int timeout = defaultTimeout)
    {
        try
        {
            HttpClient client = new HttpClient();
            if (url.StartsWith("https", System.StringComparison.OrdinalIgnoreCase))
            {
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 |
                                                       SecurityProtocolType
                                                           .Tls12; //必须加上这一句，根据需要更改值
                var handler = new HttpClientHandler();
                handler.ServerCertificateCustomValidationCallback = CheckValidationResult;
                client = new HttpClient(handler);
                client.DefaultRequestVersion = HttpVersion.Version11;
            }

            client.Timeout = TimeSpan.FromMilliseconds(timeout);
            var msg = new HttpRequestMessage(HttpMethod.Post, url);
            if (!string.IsNullOrEmpty(token))
            {
                msg.Headers.Add("Token", token);
            }
            msg.Content = new StringContent(json, Encoding.UTF8, "application/json");
            HttpResponseMessage response = client.Send(msg);
            response.EnsureSuccessStatusCode();
            StreamReader myreader = new StreamReader(response.Content.ReadAsStream(), Encoding.UTF8);
            string responseText = myreader.ReadToEnd();
            myreader.Close();
            return responseText;
        }
        catch (Exception ex)
        {
            Log.WriteException(new Exception($"POST Error: {ex.Message}, {url}, {json}, {token}"));
            throw;
        }
    }
    /// <summary>
    /// Http 上传文件
    /// </summary>
    /// <param name="postUrl"></param>
    /// <param name="token"></param>
    /// <param name="file"></param>
    /// <returns></returns>
    public static string PostFile(string postUrl, string token, IFormFile file)
    {
        //--------------------------------创建HTTP请求--------------------------------
        HttpClient client = null;
        var handler = new HttpClientHandler();
        if (postUrl.StartsWith("https", System.StringComparison.OrdinalIgnoreCase))
        {
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 |
                                                    SecurityProtocolType
                                                        .Tls12; //必须加上这一句，根据需要更改值
            handler.ServerCertificateCustomValidationCallback = CheckValidationResult;
            client = new HttpClient(handler);
            client.DefaultRequestVersion = HttpVersion.Version11;
        }
        else
        {
            client = new HttpClient(handler);
        }
        // 允许重定向
        handler.AllowAutoRedirect = true;
        
        // 设置请求方法
        var msg = new HttpRequestMessage(HttpMethod.Post, postUrl);
        // 添加token
        if (!string.IsNullOrEmpty(token))
        {
            msg.Headers.Add("token", token);
        }
        string boundary = $"---{DateTime.Now.Ticks.ToString("X")}";
        msg.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue($"multipart/form-data;charset=utf-8;boundary={boundary}");
        var postStream = new MemoryStream();
        // 添加起始分割线
        byte[] beginBoundaryBytes = Encoding.UTF8.GetBytes($"\r\n--{boundary}\r\n");
        postStream.Write(beginBoundaryBytes, 0, beginBoundaryBytes.Length);
        // 添加请求头部信息 
        string header = $"Content-Disposition:form-data;name=\"file\";filename=\"{file.Name}\"\r\nContent-Type:{file.ContentType}\r\n\r\n";
        byte[] postHeaderBytes = Encoding.UTF8.GetBytes(header);
        postStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);
        // 添加发送数据
        byte[] postArr = new byte[file.Length];
        using (Stream stream = file.OpenReadStream())
        {
            stream.Read(postArr);
        }
        postStream.Write(postArr, 0, postArr.Length);
        // 添加结束分割线
        byte[] endBoundaryBytes = Encoding.UTF8.GetBytes($"\r\n--{boundary}--\r\n");
        postStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);
        msg.Content = new StreamContent(postStream);
        //关闭流
        postStream.Close();
        // --------------------------------发送请求--------------------------------
        HttpResponseMessage response = client.Send(msg);
        response.EnsureSuccessStatusCode();
        StreamReader myreader = new StreamReader(response.Content.ReadAsStream(), Encoding.UTF8);
        string responseText = myreader.ReadToEnd();
        //关闭流
        myreader.Close();
        return responseText;
    }



    /// <summary>
    /// it运维post
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="url"></param>
    /// <param name="param"></param>
    /// <param name="token"></param>
    /// <param name="timeout"></param>
    /// <returns></returns>
    public static T? IT_Post<T>(string url, dynamic param, string? token = null, string? userid = null, int timeout = defaultTimeout)
    {
        string paramStr = JsonConvert.SerializeObject(param);
        string res = HttpITPost(url, paramStr, token, userid, timeout);
        return JsonConvert.DeserializeObject<T>(res);
    }

    /// <summary>
    /// it运维Post
    /// </summary>
    /// <param name="url"></param>
    /// <param name="json"></param>
    /// <param name="token"></param>
    /// <param name="timeout"></param>
    /// <returns></returns>
    public static string HttpITPost(string url, string json, string? token = null, string? userid = null, int timeout = defaultTimeout)
    {
        try
        {
            HttpClient client = new HttpClient();
            if (url.StartsWith("https", System.StringComparison.OrdinalIgnoreCase))
            {
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 |
                                                       SecurityProtocolType
                                                           .Tls12; //必须加上这一句，根据需要更改值
                var handler = new HttpClientHandler();
                handler.ServerCertificateCustomValidationCallback = CheckValidationResult;
                client = new HttpClient(handler);
                client.DefaultRequestVersion = HttpVersion.Version11;
            }

            client.Timeout = TimeSpan.FromMilliseconds(timeout);
            var msg = new HttpRequestMessage(HttpMethod.Post, url);
            if (!string.IsNullOrEmpty(token))
            {
                msg.Headers.Add("Authorization", $"Bearer {token}");
            }
            msg.Content = new StringContent(json, Encoding.UTF8, "application/json");
            HttpResponseMessage response = client.Send(msg);
            response.EnsureSuccessStatusCode();
            StreamReader myreader = new StreamReader(response.Content.ReadAsStream(), Encoding.UTF8);
            string responseText = myreader.ReadToEnd();
            myreader.Close();
            return responseText;
        }
        catch (Exception ex)
        {
            Log.WriteException(new Exception($"ITOperationPOST Error: {ex.Message}, {url}, {json}, {token}"));
            throw;
        }
    }

    /// <summary>
    /// it运维get
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="url"></param>
    /// <param name="token"></param>
    /// <param name="timeout"></param>
    /// <returns></returns>
    public static T? IT_Get<T>(string url, string? token = null, int timeout = defaultTimeout)
    {
        string res = HttpITGet(url, token, timeout);
        return JsonConvert.DeserializeObject<T>(res);
    }

    /// <summary>
    /// it运维Post
    /// </summary>
    /// <param name="url"></param>
    /// <param name="token"></param>
    /// <param name="timeout"></param>
    /// <returns></returns>
    public static string HttpITGet(string url, string? token = null, int timeout = defaultTimeout)
    {
        try
        {
            HttpClient client = new HttpClient();
            if (url.StartsWith("https", System.StringComparison.OrdinalIgnoreCase))
            {
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 |
                                                       SecurityProtocolType
                                                           .Tls12; //必须加上这一句，根据需要更改值
                var handler = new HttpClientHandler();
                handler.ServerCertificateCustomValidationCallback = CheckValidationResult;
                client = new HttpClient(handler);
                client.DefaultRequestVersion = HttpVersion.Version11;
            }

            client.Timeout = TimeSpan.FromMilliseconds(timeout);
            var msg = new HttpRequestMessage(HttpMethod.Get, url);
            if (!string.IsNullOrEmpty(token))
            {
                msg.Headers.Add("Authorization", $"Bearer {token}");
            }
            //msg.Content = new StringContent(json, Encoding.UTF8, "application/json");
            HttpResponseMessage response = client.Send(msg);
            response.EnsureSuccessStatusCode();
            StreamReader myreader = new StreamReader(response.Content.ReadAsStream(), Encoding.UTF8);
            string responseText = myreader.ReadToEnd();
            myreader.Close();
            return responseText;
        }
        catch (Exception ex)
        {
            Log.WriteException(new Exception($"ITOperation_GET Error: {ex.Message}, {url},{token}"));
            throw;
        }
    }
    /// <summary>
    /// it运维上传附件post
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="url"></param>
    /// <param name="param"></param>
    /// <param name="token"></param>
    /// <param name="timeout"></param>
    /// <returns></returns>
    public static T? IT_UploadFilePost<T>(string url, IFormFile file, string? token = null, int timeout = defaultTimeout)
    {
        string res = HttpITUploadFilePost(url, file, token, timeout);
        return JsonConvert.DeserializeObject<T>(res);
    }
    /// <summary>
    /// it运维上传附件Post
    /// </summary>
    /// <param name="url"></param>
    /// <param name="json"></param>
    /// <param name="token"></param>
    /// <param name="timeout"></param>
    /// <returns></returns>
    public static string HttpITUploadFilePost(string url, IFormFile file, string? token = null, int timeout = defaultTimeout)
    {
        try
        {
            HttpClient client = new HttpClient();
            if (url.StartsWith("https", System.StringComparison.OrdinalIgnoreCase))
            {
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 |
                                                       SecurityProtocolType
                                                           .Tls12; //必须加上这一句，根据需要更改值
                var handler = new HttpClientHandler();
                handler.ServerCertificateCustomValidationCallback = CheckValidationResult;
                client = new HttpClient(handler);
                client.DefaultRequestVersion = HttpVersion.Version11;
            }

            client.Timeout = TimeSpan.FromMilliseconds(timeout);
            var msg = new HttpRequestMessage(HttpMethod.Post, url);
            if (!string.IsNullOrEmpty(token))
            {
                msg.Headers.Add("Authorization", $"Bearer {token}");
            }
            var content = new MultipartFormDataContent();
            // 将IFormFile转换为Stream
            var fileContent = new StreamContent(file.OpenReadStream());
            content.Add(fileContent, "formFile", file.FileName);
            msg.Content = content;
            
            HttpResponseMessage response = client.Send(msg);
            response.EnsureSuccessStatusCode();
            StreamReader myreader = new StreamReader(response.Content.ReadAsStream(), Encoding.UTF8);
            string responseText = myreader.ReadToEnd();
            myreader.Close();
            return responseText;
        }
        catch (Exception ex)
        {
            Log.WriteException(new Exception($"ITOperationPOST Error: {ex.Message}, {url}, {token}"));
            throw;
        }
    }


    /// <summary>
    /// HttpGetString
    /// </summary>
    /// <param name="url"></param>
    /// <param name="timeout"></param>
    /// <returns></returns>
    public static async Task<string> HttpGetStringAsync(string url, int timeout = defaultTimeout)
    {
        try
        {
            HttpClient client = new HttpClient();
            if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
            {
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 |
                                                       SecurityProtocolType
                                                           .Tls12; //必须加上这一句，根据需要更改值
                var handler = new HttpClientHandler();
                handler.ServerCertificateCustomValidationCallback = CheckValidationResult;
                client = new HttpClient(handler);
                client.DefaultRequestVersion = HttpVersion.Version11;
            }
            client.Timeout = TimeSpan.FromMilliseconds(timeout);
            var responseText = await client.GetStringAsync(url);
            return responseText;
        }
        catch (Exception ex)
        {
            Log.WriteException(new Exception($"GETString Error: {ex.Message}, {url}"));
            throw;
        }
    }

    public static async Task DownloadImageAsync(string imageUrl, string localPath)
    {

        HttpClient client = new HttpClient();
        if (imageUrl.StartsWith("https", StringComparison.OrdinalIgnoreCase))
        {
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 |
                                                    SecurityProtocolType
                                                        .Tls12; //必须加上这一句，根据需要更改值
            var handler = new HttpClientHandler();
            handler.ServerCertificateCustomValidationCallback = CheckValidationResult;
            client = new HttpClient(handler);
            client.DefaultRequestVersion = HttpVersion.Version11;
        }
        // 发送 GET 请求获取图片
        HttpResponseMessage response = await client.GetAsync(imageUrl);
        response.EnsureSuccessStatusCode(); // 确保请求成功

        // 读取响应内容作为字节数组
        byte[] imageData = await response.Content.ReadAsByteArrayAsync();

        // 将字节数组写入本地文件
        using (FileStream fileStream = new FileStream(localPath, FileMode.Create, FileAccess.Write))
        {
            await fileStream.WriteAsync(imageData, 0, imageData.Length);
        }
    }
}
